﻿using SharpDX.Direct3D11;
using System.Windows.Forms;
using SharpDX;
using SharpDX.D3DCompiler;
using SharpDX.DXGI;
using SharpDX.Windows;
using Device = SharpDX.Direct3D11.Device;
using Engine.Serialize;

namespace Engine
{
    public class MaterialContainer : ResourceContainer
    {
        public string Name = "";

        public EffectContainer Effect = null;
        public TextureContainer Diffuse = null;
        public TextureContainer UV2Diffuse = null;
        public TextureContainer NormalMap = null;
        public TextureContainer SpecularMap = null;
        public TextureContainer SelfMap = null;
        public Vector3 DiffuseMultipler = new Vector3(1, 1, 1);
        public Vector3 SpecularMultipler = new Vector3(1, 1, 1);
        public Vector3 SelfMultipler = new Vector3(1, 1, 1);
        public bool DoubleSide = false;
        public int Alpha = 127;

        public SamplerState DiffuseSamplerState, UV2DiffuseSamplerState, NormalMapSamplerState, SpecularMapSamplerState, SelfMapSamplerState;

        public bool MipNormal, MipSpecular, MipDiffuse, MipSelf, MipUV2Diffuse;

        public MaterialContainer(Material M)
        {
            if (M != null)
            {
                Name = M.MaterialName;
                InputElement[] IE = GetInputElementFromShaderName(M.Shader);
                Effect = ContentManager.LoadEffect(M.Shader, IE);
                Diffuse = ContentManager.LoadTexture2D(M.Diffuse);
                UV2Diffuse = ContentManager.LoadTexture2D(M.UV2Diffuse);
                NormalMap = ContentManager.LoadTexture2D(M.NormalMap);
                SpecularMap = ContentManager.LoadTexture2D(M.SpecularMap);
                SelfMap = ContentManager.LoadTexture2D(M.SelfMap);

                MipNormal = NormalMap.Texture2d.Description.MipLevels > 7;
                MipSpecular = SpecularMap.Texture2d.Description.MipLevels > 7;
                MipDiffuse = Diffuse.Texture2d.Description.MipLevels > 7;
                MipSelf = SelfMap.Texture2d.Description.MipLevels > 7;
                MipUV2Diffuse = UV2Diffuse.Texture2d.Description.MipLevels > 7;

                DiffuseMultipler = M.DiffuseMultipler;
                SpecularMultipler = M.SpecularMultipler;
                SelfMultipler = M.SelfMultipler;
                DoubleSide = M.DoubleSide;
                Alpha = M.Alpha;

                if (Global.Settings.TextureFiltering > -1)
                {
                    if (MipDiffuse) DiffuseSamplerState = DrawHelper.SamplAnsWrapMip;
                    else DiffuseSamplerState = DrawHelper.SamplAnsWrap;
                    if (MipSpecular) SpecularMapSamplerState = DrawHelper.SamplAnsWrapMip;
                    else SpecularMapSamplerState = DrawHelper.SamplAnsWrap;
                    if (MipNormal) NormalMapSamplerState = DrawHelper.SamplAnsWrapMip;
                    else NormalMapSamplerState = DrawHelper.SamplAnsWrap;
                    if (MipSelf) SelfMapSamplerState = DrawHelper.SamplAnsWrapMip;
                    else SelfMapSamplerState = DrawHelper.SamplAnsWrap;
                    if (MipUV2Diffuse) UV2DiffuseSamplerState = DrawHelper.SamplAnsWrapMip;
                    else UV2DiffuseSamplerState = DrawHelper.SamplAnsWrap;
                }
                else if (Global.Settings.TextureFiltering == -1)
                {
                    if (MipDiffuse) DiffuseSamplerState = DrawHelper.SamplLinWrapMip;
                    else DiffuseSamplerState = DrawHelper.SamplLinWrap;
                    if (MipSpecular) SpecularMapSamplerState = DrawHelper.SamplLinWrapMip;
                    else SpecularMapSamplerState = DrawHelper.SamplLinWrap;
                    if (MipNormal) NormalMapSamplerState = DrawHelper.SamplLinWrapMip;
                    else NormalMapSamplerState = DrawHelper.SamplLinWrap;
                    if (MipSelf) SelfMapSamplerState = DrawHelper.SamplLinWrapMip;
                    else SelfMapSamplerState = DrawHelper.SamplLinWrap;
                    if (MipUV2Diffuse) UV2DiffuseSamplerState = DrawHelper.SamplLinWrapMip;
                    else UV2DiffuseSamplerState = DrawHelper.SamplLinWrap;
                }
                else
                {
                    if (MipDiffuse) DiffuseSamplerState = DrawHelper.SamplPntWrapMip;
                    else DiffuseSamplerState = DrawHelper.SamplPntWrap;
                    if (MipSpecular) SpecularMapSamplerState = DrawHelper.SamplPntWrapMip;
                    else SpecularMapSamplerState = DrawHelper.SamplPntWrap;
                    if (MipNormal) NormalMapSamplerState = DrawHelper.SamplPntWrapMip;
                    else NormalMapSamplerState = DrawHelper.SamplPntWrap;
                    if (MipSelf) SelfMapSamplerState = DrawHelper.SamplPntWrapMip;
                    else SelfMapSamplerState = DrawHelper.SamplPntWrap;
                    if (MipUV2Diffuse) UV2DiffuseSamplerState = DrawHelper.SamplPntWrapMip;
                    else UV2DiffuseSamplerState = DrawHelper.SamplPntWrap;
                }
            }
        }

        public InputElement[] GetInputElementFromShaderName(string ShaderName)
        {
            switch (ShaderName)
            {
                case "BaseShader":
                    return new InputElement[]{ 
                new InputElement("POSITION", 0, Format.R32G32B32_Float, 0, 0),
                new InputElement("TEXCOORD", 0, Format.R16G16_Float, 12, 0),
                new InputElement("TEXCOORD", 1, Format.R16G16_Float, 16, 0),
                new InputElement("NORMAL", 0, Format.R8G8B8A8_UNorm, 20, 0),//w = bone3.w[0]
                new InputElement("TANGENT", 0, Format.R8G8B8A8_UNorm, 24, 0),//w = bone3.w[1]
                new InputElement("BLENDINDICES", 0, Format.R8G8B8A8_UNorm, 28, 0)};// bone3.w[2], bone3.i[0], bone3.i[1], bone3.i[2]

                default:
                    return new InputElement[]{ 
                new InputElement("POSITION", 0, Format.R32G32B32_Float, 0, 0),
                new InputElement("TEXCOORD", 0, Format.R16G16_Float, 12, 0),
                new InputElement("TEXCOORD", 1, Format.R16G16_Float, 16, 0),
                new InputElement("NORMAL", 0, Format.R8G8B8A8_UNorm, 20, 0),//w = bone3.w[0]
                new InputElement("TANGENT", 0, Format.R8G8B8A8_UNorm, 24, 0),//w = bone3.w[1]
                new InputElement("BLENDINDICES", 0, Format.R8G8B8A8_UNorm, 28, 0)};// bone3.w[2], bone3.i[0], bone3.i[1], bone3.i[2]
            }
        }
    }
}
